<template>
  <div class="app-container">
    <el-row>
      <el-form size="mini" style="padding-top: 15px; font-size: 12px">
        <el-form-item v-model="form.createTime" label="创建时间">
          <date-picker/>
        </el-form-item>
        <el-form-item label="任务状态" @change="handleStatusChange">
          <el-radio-group v-model="form.status" >
            <el-radio :label="0">正常</el-radio>
            <el-radio :label="1">禁用</el-radio>
          </el-radio-group>
        </el-form-item>
      </el-form>
    </el-row>
    <el-row>
      <el-button type="primary" icon="el-icon-plus" size="mini" @click="handleAdd" v-hasPermit="['datax:job:add']">新增</el-button>
    </el-row>
    <el-row style="position: initial">
      <div v-if="jobList.length > 0" class="cart-list-wrapper">
        <el-card class="box-card" v-for="(job, index) in jobList">
          <div slot="header" class="clearfix card-header">
            <span style="font-weight:bold; font-size: 24px; margin-right:15px; color: #d63200">#{{ index + 1 }}</span>
            <span style="vertical-align: text-bottom">{{ job.jobName }}</span>
            <el-tag :type="job.status === 0 ? 'success' : 'danger'" style="float: right; line-height: 36px; height: 36px;">正常</el-tag>
          </div>
          <div class="card-body">
            <el-row class="clearfix" style="margin-bottom: 15px;">
              <span class="job-desc">{{ job.jobDesc }}</span>
              <el-button style="float: right;" type="primary" size="small">立即运行</el-button>
              <el-button style="float: right; margin-right: 15px;" type="danger" size="small">删除任务</el-button>
            </el-row>
            <el-collapse v-model="activeNames">
              <el-collapse-item name="reader" class="clearfix">
                <template slot="title">
                  reader template
                </template>
                <json-viewer :value="form.readerParams ? JSON.parse(job.readerParams) : '暂无任何配置'"
                             :expand-depth=5
                             copyable
                             boxed/>
                <el-button type="text" style="float: right">查看详情</el-button>
              </el-collapse-item>
              <el-collapse-item name="writer" class="clearfix">
                <template slot="title">
                  writer template
                </template>
                <json-viewer :value="form.writerParams ? JSON.parse(job.writerParams) : '暂无任何配置'"
                             :expand-depth=5
                             copyable
                             boxed/>
                <el-button type="text" style="float: right">查看详情</el-button>
              </el-collapse-item>
            </el-collapse>
          </div>
          <div class="card-footer clearfix">
            <span class="card-footer--small">创建时间：{{ job.createTime }}</span>
            <span class="card-footer--small">下次运行时间：</span>
          </div>
        </el-card>
      </div>
      <div v-else class="empty-list">
        <div>
          <svg-icon icon-class="empty" class="empty-list-icon"/>
        </div>
        <div>
          抱歉，没有找到任务~~~
        </div>
      </div>
    </el-row>
    <el-row>
      <el-pagination
        hide-on-single-page
        background
        layout="prev, pager, next"
        :current-page="queryParams.pageNum"
        :page-size="queryParams.pageSize"
        :total="queryParams.total">
      </el-pagination>
    </el-row>

    <vxe-modal v-model="open"
               :esc-closable="true"
               transfer
               show-footer
               lock-view
               lock-scroll
               :title="title"
               fullscreen
               remember
               resize>
      <template v-slot>
        <el-divider style="color: #d63200;">任务基本信息</el-divider>
        <el-row>
          <el-form ref="form" size="small" :model="form" label-width="100px">
            <el-row>
              <el-col :span="12">
                <el-form-item label="任务名称" prop="jobName">
                  <el-input v-model="form.jobName" />
                </el-form-item>
              </el-col>
            </el-row>
            <el-row>
              <el-col :span="12">
                <el-form-item label="任务描述" prop="jobDesc">
                  <el-input v-model="form.jobDesc"></el-input>
                </el-form-item>
              </el-col>
            </el-row>
            <el-row>
              <el-col :span="12">
                <el-form-item label="Reader数据源" prop="srcSourceId">
                  <el-select v-model="form.srcSourceId">
                    <el-option v-for="item in datasourceOptions"
                               :key="item.datasource"
                               :label="item.databaseType + '-' + item.databaseName "
                               :value="item.id"
                    />
                  </el-select>
                </el-form-item>
              </el-col>
            </el-row>
            <el-row>
              <el-col :span="12">
                <el-form-item label="Writer数据源" prop="dstSourceId">
                  <el-select v-model="form.dstSourceId">
                    <el-option v-for="item in datasourceOptions"
                               :key="item.datasource"
                               :label="item.databaseType + '-' + item.databaseName "
                               :value="item.id"
                    />
                  </el-select>
                </el-form-item>
              </el-col>
            </el-row>
          </el-form>
        </el-row>
        <el-divider style="color: #d63200">Reader配置</el-divider>
        <el-row>
          <el-col :span="12">
            <el-form v-model="form.readerParams" label-width="100px" size="small">
              <el-form-item label="配置模式" prop="type">
                <el-radio-group v-model="form.readerParams.type">
                  <el-radio-button label="meta">meta模式</el-radio-button>
                  <el-radio-button label="sql">sql模式</el-radio-button>
                </el-radio-group>
              </el-form-item>
              <div v-if="form.readerParams.type === 'meta'">
                <el-form-item prop="parameter.connection.table">
                  <template slot="label">
                    <el-tooltip effect="dark" content="所选取的需要同步的表。使用JSON的数组描述，因此支持多张表同时抽取。当配置为多张表时，用户自己需保证多张表是同一schema结构" placement="right">
                      <span>数据表<i class="el-icon el-icon-info"/></span>
                    </el-tooltip>
                  </template>
                  <vxe-pulldown ref="readTable">
                    <template v-slot>
                      <vxe-input v-model="form.readerParams.parameter.connection.table"
                                 style="font-size: 12px; width: 250px;"
                                 clearable
                                 @focus="handleReaderTableFocus"
                                 @keyup="handleReaderTableKeyUp"
                                 :disabled="form.srcSourceId == null"></vxe-input>
                    </template>
                    <template v-slot:dropdown>
                      <vxe-list height="200" :data="readerTableList" auto-resize style="z-index: 1000000;" :loading="loading">
                        <template v-slot="{ items }">
                          <div v-for="item in items" :key="item" @click="handleReaderTableSelect(item)">
                            <span>{{ item }}</span>
                          </div>
                        </template>
                      </vxe-list>
                    </template>
                  </vxe-pulldown>
                </el-form-item>
                <el-form-item prop="parameter.column">
                  <template slot="label">
                    <el-tooltip effect="dark" content="所配置的表中需要同步的列名集合，使用JSON的数组描述字段信息。用户使用*代表默认使用所有列配置，例如['*']" placement="right">
                      <span>数据表字段<i class="el-icon el-icon-info"/></span>
                    </el-tooltip>
                  </template>
                  <el-transfer
                    v-model="form.readerParams.parameter.column"
                    :titles="['未选择', '已选择']"
                    :disabled="form.srcSourceId == undefined"
                    :loading="loading"
                    :props="{
                        key: 'name',
                        label: 'name'
                       }"
                    :data="readerColumns">
                  </el-transfer>
                </el-form-item>
                <el-form-item prop="parameter.where">
                  <template slot="label">
                    <el-tooltip effect="dark" content="描述条件" placement="right">
                      <span>where语句<i class="el-icon el-icon-info"/></span>
                    </el-tooltip>
                  </template>
                  <el-input v-model="form.readerParams.parameter.where"></el-input>
                </el-form-item>
                <el-form-item prop="parameter.fetchSize">
                  <template slot="label">
                    <el-tooltip effect="dark" placement="right" content="该配置项定义了插件和数据库服务器端每次批量数据获取条数，该值决定了DataX和服务器端的网络交互次数，能够较大的提升数据抽取性能。">
                      <span>获取条数<i class="el-icon el-icon-info"/></span>
                    </el-tooltip>
                  </template>
                  <el-input-number v-model="form.readerParams.parameter.fetchSize" :min="1024"/>
                </el-form-item>
              </div>
              <div v-else style="margin-top: 10px;">
                <el-form-item prop="parameter.connection.querySql">
                  <template slot="label">
                    <el-tooltip effect="dark" content="当用户配置querySql时，reader直接忽略table、column、where条件的配置。" placement="right">
                      <span>查询语句<i class="el-icon el-icon-info"/></span>
                    </el-tooltip>
                  </template>
                  <el-input
                    type="textarea"
                    :rows="6"
                    placeholder="请输入查询的SQL语句，如select * from tskuplu where rownum <= 10"
                    v-model="form.readerParams.parameter.connection.querySql">
                  </el-input>
                </el-form-item>
              </div>
            </el-form>
          </el-col>
        </el-row>
        <el-divider style="color: #d63200">Writer配置</el-divider>
        <el-row>
          <el-col :span="12">
            <el-form v-model="form.writerParams" size="small" label-width="100px">
              <el-form-item prop="parameter.writeMode">
                <template slot="label">
                  <el-tooltip effect="dark" content="控制写入数据到目标表采用 insert into 或者 replace into 或者 on duplicate key update 语句" placement="right">
                    <span>写入方式<i class="el-icon el-icon-info"/></span>
                  </el-tooltip>
                </template>
                <el-radio-group v-model="form.writerParams.parameter.writeMode">
                  <el-radio-button label="insert"/>
                  <el-radio-button label="replace"/>
                  <el-radio-button label="update"/>
                </el-radio-group>
              </el-form-item>
              <el-form-item prop="parameter.batchSize">
                <template slot="label">
                  <el-tooltip effect="dark" placement="right" content="一次性批量提交的记录数大小，该值可以极大减少DataX与数据库的网络交互次数，并提升整体吞吐量。但是该值设置过大可能会造成DataX运行进程OOM情况。">
                    <span>记录数大小<i class="el-icon el-icon-info"/></span>
                  </el-tooltip>
                </template>
                <el-input-number v-model="form.writerParams.parameter.batchSize" :min="512"/>
              </el-form-item>
              <el-form-item prop="parameter.connection.table">
                <template slot="label">
                  <el-tooltip effect="dark" content="目的表的表名称。支持写入一个或者多个表。当配置为多张表时，必须确保所有表结构保持一致。" placement="right">
                    <span>数据表<i class="el-icon el-icon-info"/></span>
                  </el-tooltip>
                </template>
                <vxe-pulldown ref="writeTable">
                  <template v-slot>
                    <vxe-input v-model="form.writerParams.parameter.connection.table"
                               style="font-size: 12px; width: 250px;"
                               @focus="handleWriterTableFocus"
                               clearable
                               @keyup="handleWriterTableKeyUp"
                               :disabled="form.dstSourceId == undefined"></vxe-input>
                  </template>
                  <template v-slot:dropdown>
                    <vxe-list height="200" :data="writerTableList" :loading="loading" auto-resize>
                      <template v-slot="{ items }">
                        <div v-for="item in items" :key="item" @click="handleWriterTableSelect(item)">
                          <span>{{ item }}</span>
                        </div>
                      </template>
                    </vxe-list>
                  </template>
                </vxe-pulldown>
              </el-form-item>
              <el-form-item prop="parameter.connection.table">
                <template slot="label">
                  <el-tooltip effect="dark" content="目的表需要写入数据的字段,字段之间用英文逗号分隔。例如: 'column': ['id','name','age']。如果要依次写入全部列，使用*表示, 例如: 'column': ['*']。" placement="right">
                    <span>数据表字段<i class="el-icon el-icon-info"/></span>
                  </el-tooltip>
                </template>
                <el-transfer
                  v-model="form.writerParams.parameter.column"
                  :titles="['未选择', '已选择']"
                  :disabled="form.dstSourceId == undefined"
                  :props="{
                    key: 'name',
                    label: 'name'
                   }"
                  :data="writerColumns">
                </el-transfer>
              </el-form-item>
              <el-form-item prop="parameter.preSql">
                <template slot="label">
                  <el-tooltip effect="dark" content="写入数据到目的表前，会先执行这里的标准语句." placement="right">
                    <span>写入前语句<i class="el-icon el-icon-info"/></span>
                  </el-tooltip>
                </template>
                <el-input
                  type="textarea"
                  :rows="6"
                  placeholder="如果 Sql 中有你需要操作到的表名称，请使用 @table 表示，这样在实际执行 Sql 语句时，会对变量按照实际表名称进行替换。比如你的任务是要写入到目的端的100个同构分表(表名称为:datax_00,datax01, ... datax_98,datax_99)，并且你希望导入数据前，先对表中数据进行删除操作，那么你可以这样配置：preSql:[delete from 表名]，效果是：在执行到每个表写入数据前，会先执行对应的 delete from 对应表名称"
                  v-model="form.writerParams.parameter.preSql">
                </el-input>
              </el-form-item>
              <el-form-item prop="parameter.postSql">
                <template slot="label">
                  <el-tooltip effect="dark" content="写入数据到目的表后，会执行这里的标准语句。" placement="right">
                    <span>写入后语句<i class="el-icon el-icon-info"/></span>
                  </el-tooltip>
                </template>
                <el-input
                  type="textarea"
                  :rows="6"
                  placeholder="原理同preSql"
                  v-model="form.writerParams.parameter.postSql">
                </el-input>
              </el-form-item>
            </el-form>
          </el-col>
        </el-row>
      </template>
      <template v-slot:footer>
        <div style="text-align: center">
          <el-button type="primary" @click="submitForm">确 定</el-button>
          <el-button @click="open = false">取 消</el-button>
        </div>
      </template>
    </vxe-modal>
  </div>

</template>

<script>
  import DatePicker from "@/components/DatePicker/index";
  import SvgIcon from "@/components/SvgIcon";
  import JsonViewer from 'vue-json-viewer';
  import { listJob, addJobConf, deleteJobConf, updateJobConf } from '@/api/datax/job';
  import { listDatasource, getTables, getColumns } from '@/api/datax/datasource'
  import { clone } from "@/utils";

  export default {
    name: "JobConf",
    components: {DatePicker, JsonViewer, SvgIcon},
    data() {
      return {
        readerTableList: [],
        writerTableList: [],
        readerTables: [],
        readerColumns: [],
        writerTables: [],
        writerColumns: [],
        form: {
          status: 0,
          jobName: undefined,
          jobDesc: undefined,
          srcSourceId: undefined,
          dstSourceId: undefined,
          readerParams: {
            type: "meta",
            name: "",
            parameter: {
              fetchSize: 1024,
              column: [],
              where: "",
              connection: {
                table: "",
                querySql: ""
              }
            }
          },
          writerParams: {
            name: "",
            parameter: {
              // insert/replace/update
              writeMode: "insert",
              batchSize: 1024,
              dateFormat: "yyyy-MM-dd hh:mm:ss",
              encoding: "UTF-8",
              column: [],
              preSql: "",
              postSql: "",
              connection: {
                table: ""
              }
            }
          },
          createTime: undefined,
        },
        title: undefined,
        open: false,
        loading: false,
        datasourceOptions: [],
        statusOptions: [],
        jobList: [],
        activeNames: ['reader', 'writer'],
        queryParams: {
          pageNum: 1,
          pageSize: 10,
          total: 0
        }
      }
    },
    created() {
      this.getList();
      this.getDicts("sys_job_run_status").then(response => {
        this.statusOptions = response.data;
      });
      listDatasource().then(response => {
        this.datasourceOptions = response.rows;
      })
    },
    methods: {
      handleReaderTableKeyUp() {
        const value = this.form.readerParams.parameter.connection.table
        this.readerTableList = value ? this.readerTables.filter(item => item.toLowerCase().indexOf(value.toLowerCase()) > -1) : this.readerTables;
      },
      handleWriterTableKeyUp() {
        const value = this.form.writerParams.parameter.connection.table
        this.writerTableList = value ? this.writerTables.filter(item => item.toLowerCase().indexOf(value.toLowerCase()) > -1) : this.writerTables;
      },
      handleReaderTableSelect(table) {
        this.form.readerParams.parameter.connection.table = table;
        this.$refs.readTable.hidePanel().then(() => {
          this.loading = true;
          getColumns(this.form.srcSourceId, table).then(res => {
            this.readerColumns = res.rows;
            this.loading = false;
            this.readerTables = [];
            this.readerTableList = [];
          }).catch(_ => {
            this.loading = false;
          });
        });
      },
      handleWriterTableSelect(table) {
        this.form.writerParams.parameter.connection.table = table;
        this.$refs.writeTable.hidePanel().then(() => {
          this.loading = true;
          getColumns(this.form.dstSourceId, table).then(res => {
            this.writerColumns = res.rows;
            this.loading = false;
            this.writerTables = [];
            this.writerTableList = [];
          }).catch(_ => {
            this.loading = false;
          });
        });
      },
      handleReaderTableFocus() {
        this.$refs.readTable.showPanel().then(() => {
          this.loading = true;
          getTables(this.form.srcSourceId).then(res => {
            this.readerTables = res.rows;
            this.readerTableList = this.readerTables;
            this.loading = false;
          }).catch(_ => {
            this.loading = false;
          });
        });
      },
      handleWriterTableFocus() {
        this.$refs.writeTable.showPanel().then(() => {
          this.loading = true;
          getTables(this.form.dstSourceId).then(res => {
            this.writerTables = res.rows;
            this.writerTableList = this.writerTables;
            this.loading = false;
          }).catch(_ => {
            this.loading = false;
          });
        });
      },
      handleStatusChange(val) {

      },
      handleAdd() {
        this.open = true
        this.title = "创建任务模板"
      },
      submitForm() {
        if (this.title === "创建任务模板") {
          // 提交数据前，要对数据做预处理，使之满足datax的配置文件格式
          console.log(this.form);
          const postData = clone(this.form);
          console.log(postData);
          postData.writerParams.parameter.connection.table = postData.writerParams.parameter.connection.table.split(",");
          postData.readerParams.parameter.connection.table = postData.readerParams.parameter.connection.table.split(",");
          postData.writerParams = JSON.stringify(postData.writerParams);
          postData.readerParams = JSON.stringify(postData.readerParams);
          addJobConf(postData).then(res => {
            this.$notify({
              type: 'success',
              title: '创建成功',
              duration: 2000
            });
            this.open = !this.open;
          }).catch(res => {
            this.$notify({
              type: 'error',
              title: '创建失败',
              message: res.msg,
              duration: 3000
            });
          })
        }
      },
      getList() {
        const query = this.$route.query
        this.queryParams.jobId = query.jobId
        this.loading = true;
        listJob().then(response => {
            this.jobList = response.rows;
            this.queryParams.total = response.total;
            this.loading = false;
          }
        );
      },
    }
  }
</script>

<style scoped>

  .cart-list-wrapper {
    margin-top: 20px;
  }

  .box-card {
    margin-bottom: 20px;
  }

  .card-header {
    font-size: 14px;
    color: #303133;
  }

  .box-card .el-collapse-item {
    margin-bottom: 20px;
  }

  .card-footer {
    margin: 15px 0;
  }
  .card-footer--small {
    font-size: 11px;
    color: #909399;
  }

  .card-footer--small + .card-footer--small {
    margin-left: 25px;
  }

  .empty-list {
    font-size: 14px;
    color: #909399;
    width: 200px;
    height: 200px;
    margin-left: -100px;
    margin-top: -100px;
    position: absolute;
    top: 50%;
    left: 50%;
    text-align: center;
  }

  .empty-list-icon {
    font-size: 200px;
  }

  .box-card .job-desc {
    font-size: 14px;
  }

  .el-icon {
    margin-left: 5px;
  }

  .el-divider__text {
    color: #d63200 !important;
    font-weight: bold;
  }

</style>
